package com.cp.exception;

import com.cp.common.CommonResult;
import com.cp.common.HttpStatusCode;
import com.cp.util.CommonResUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 全局异常捕获
 *
 * @author YangXiaoLong
 * 2021/9/8 7:58
 */
@Slf4j
@RestControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {

    /**
     * des:
     * 业务异常
     *
     * @param e e
     * @return {@link  Object }
     * @author captain
     * @date 2021/9/8 13:06
     */
    @ExceptionHandler(value = BusinessException.class)
    public CommonResult<Object> businessHandle(BusinessException e) {
        log.error("业务异常! 原因：{}", e.getMessage(), e);
        return CommonResUtils.error(e.getCode(), e.getMessage());
    }

    /**
     * des:
     * 捕捉 validator  Controller 参数校验
     *
     * @param e 错误信息
     * @return {@link CommonResult<Object> }
     * @author captain
     * @date 2021/9/12 18:25
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public CommonResult<Object> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error("参数绑定校验异常! 原因：{}", e.getMessage(), e);
        //错误列表
        List<ObjectError> res = e.getBindingResult().getAllErrors();
        return CommonResUtils.error(HttpStatusCode.ERROR, res
                .stream()
                .map(DefaultMessageSourceResolvable::getDefaultMessage)
                .collect(Collectors.joining(";")));
    }

    /**
     * des:
     * 捕捉 validator  Controller 参数校验
     *
     * @param e 错误信息
     * @return {@link CommonResult<Object> }
     * @author captain
     * @date 2021/9/12 18:25
     */
    @ExceptionHandler(value = BindException.class)
    public CommonResult<Object> handleMethodBindException(BindException e) {
        log.error("参数绑定校验异常! 原因：{}", e.getMessage(), e);
        //错误列表
        List<ObjectError> res = e.getBindingResult().getAllErrors();
        return CommonResUtils.error(HttpStatusCode.ERROR, res
                .stream()
                .map(DefaultMessageSourceResolvable::getDefaultMessage)
                .collect(Collectors.joining(";")));
    }

    /**
     * des:
     * 其他非特殊异常处理 为 系统错误
     *
     * @param e e
     * @return {@link CommonResult<Object> }
     * @author captain
     * @date 2021/9/12 19:27
     */
    @ExceptionHandler(value = Exception.class)
    public CommonResult<Object> exceptionHandle(Exception e) {
        log.error("系统异常! 原因：{}", e.getMessage(), e);
        return CommonResUtils.error(HttpStatusCode.ERROR, "系统打盹了！");
    }
}
